#include <PDM.h>
#include <RingBuf.h>

const uint32_t MIC_NUM_CHANNELS = 1;
const uint32_t MIC_SAMPLE_RATE = 16000; // 16000 or 41667
const uint32_t MIC_GAIN = 20;	// 0-255; defaults to 20

const uint32_t MIC_BUFFER_SIZE = 128;	// in bytes.
int16_t micBuffer[MIC_BUFFER_SIZE];

const uint32_t AUDIO_BUFFER_NUM_SAMPLES = 2048;
RingBuf<int16_t, AUDIO_BUFFER_NUM_SAMPLES> audioSampleRingBuffer;


void clearAudioSampleRingBuffer() {
	while (!audioSampleRingBuffer.isEmpty()) {
		int16_t s; audioSampleRingBuffer.pop(s);
	}
}

void onReceiveCallback() {
	const int bytesAvailable = PDM.available();
	const int bytesRead = PDM.read(micBuffer, bytesAvailable);
	const int samplesRead = bytesRead / 2;
	for (int i=0; i<samplesRead && !audioSampleRingBuffer.isFull(); i++) {
		int16_t s = micBuffer[i];
		audioSampleRingBuffer.push(s);
	}
}

void printBufferedAudioSamples() {
	while (!audioSampleRingBuffer.isEmpty()) {
		int16_t s;
		audioSampleRingBuffer.pop(s);
		Serial.println(s);
	}
}


void setup() {
	Serial.begin(9600);
	clearAudioSampleRingBuffer();
	PDM.setGain(MIC_GAIN);
	PDM.setBufferSize(MIC_BUFFER_SIZE);
	PDM.onReceive(onReceiveCallback);
	if (!PDM.begin(MIC_NUM_CHANNELS, MIC_SAMPLE_RATE)) {
		Serial.println("Failed to start PDM microphone.");
		while(1);
	}
}

void loop() {
	printBufferedAudioSamples();
}